use anyhow::Result;
use dashmap::DashMap;
use prost::Message;
use std::net::{IpAddr, SocketAddr};
use std::sync::Arc;
use tokio::net::UdpSocket;
use tokio::sync::Mutex;

use tracing::{debug, error, info, trace, warn};

use crate::constants::WAR3_PORT;
use crate::network::{ClientConnection, SplitTcp};
use crate::proto::{ClientListUpdate, DataForward, IpAssignment, MessageType, War3Message};
use crate::utils::receive_protobuf_message;
use crate::war3_server::War3Server;

/// 客户端状态
pub struct ClientState {
    pub server_addr: SocketAddr,
    pub local_war3_game_ip: IpAddr,
    pub war3_servers: Arc<DashMap<String, Arc<War3Server>>>,
    pub my_war3_ip: Arc<Mutex<Option<String>>>,
}

impl ClientState {
    pub fn new(server_addr: SocketAddr, local_war3_game_ip: IpAddr) -> Self {
        Self {
            server_addr,
            local_war3_game_ip,
            war3_servers: Arc::new(DashMap::new()),
            my_war3_ip: Arc::new(Mutex::new(None)),
        }
    }
}

/// 处理服务器消息
pub async fn handle_server_messages(
    state: Arc<ClientState>,
    connection: Arc<ClientConnection>,
) -> Result<()> {
    info!("Starting server message loop (using split read half - no lock contention!)");

    // 获取读半部分（不会与写半部分竞争锁）
    let read_half = connection.read_half();

    loop {
        // 获取读锁（不会与写锁竞争）
        let mut reader = read_half.lock().await;
        info!("Acquired read lock for receiving message");

        match receive_protobuf_message::<War3Message>(&mut *reader).await {
            Ok(message) => {
                // 只对非DataForward消息记录debug级别日志
                if message.r#type != MessageType::DataForward as i32 {
                    debug!("Received message: type={:?}, target_ip={}", message.r#type, message.target_ip);
                } else {
                    info!("Received DataForward: {} -> {}", message.source_ip, message.target_ip);
                }
                drop(reader); // 释放读锁

                // 处理消息
                match message.r#type {
                    x if x == MessageType::ClientConnectResult as i32 => {
                        handle_initial_connection(&state, &connection, message).await?;
                    }
                    x if x == MessageType::DataForward as i32 => {
                        handle_data_forward(Arc::clone(&state), message).await?;
                    }
                    x if x == MessageType::ClientListUpdate as i32 => {
                        handle_client_list_update(&state, &connection, message).await?;
                    }
                    _ => {
                        warn!("Unknown message type: {:?}", message.r#type);
                    }
                }
            }
            Err(e) => {
                error!("Error receiving message: {}", e);
                break;
            }
        }
    }

    Ok(())
}

/// 处理初始连接响应
async fn handle_initial_connection(
    state: &Arc<ClientState>,
    connection: &Arc<ClientConnection>,
    message: War3Message,
) -> Result<()> {
    let ip_assignment = IpAssignment::decode(&message.payload[..])?;
    let my_ip = ip_assignment.assigned_ip.clone();

    *state.my_war3_ip.lock().await = Some(my_ip.clone());
    info!("Assigned War3 IP: {}", my_ip);

    // 为其他客户端创建War3Server
    for other_ip in ip_assignment.other_ips {
        if !other_ip.is_empty() {
            info!("Creating War3Server for other IP: {}", other_ip);
            add_war3_server(Arc::clone(state), &other_ip, Arc::clone(connection), &my_ip).await?;
        }
    }

    Ok(())
}

/// 处理数据转发
async fn handle_data_forward(state: Arc<ClientState>, message: War3Message) -> Result<()> {
    let data_forward = DataForward::decode(&message.payload[..])?;
    let from_ip = data_forward.from_ip.clone();
    let target_ip = message.target_ip.clone();

    info!(
        "Handling data forward: from={}, target={}, {} bytes",
        from_ip,
        target_ip,
        data_forward.data.len()
    );

    // 查找target_ip对应的War3Server（用于转发给其他客户端）
    if let Some(war3_server) = state.war3_servers.get(&target_ip) {
        info!("Found War3Server for {}, sending UDP data", target_ip);
        
        // 通过War3Server发送UDP数据
        if let Err(e) = war3_server.send_udp_data(&data_forward.data).await {
            error!("Failed to send UDP data: {}", e);
        } else {
            info!("Successfully sent UDP data to War3Server for {}: {} bytes", target_ip, data_forward.data.len());
        }
    } else {
        info!("War3Server not found for target IP: {}", target_ip);
    }

    Ok(())
}

/// 处理客户端列表更新
async fn handle_client_list_update(state: &Arc<ClientState>, connection: &Arc<ClientConnection>, message: War3Message) -> Result<()> {
    let client_list = ClientListUpdate::decode(&message.payload[..])?;
    info!("Received client list update: {} clients", client_list.client_ips.len());

    // 获取自己的IP
    let my_ip = {
        let my_ip_guard = state.my_war3_ip.lock().await;
        my_ip_guard.as_ref().cloned()
    };

    if let Some(ref my_ip) = my_ip {
        // 为新客户端创建War3Server
        for other_ip in &client_list.client_ips {
            if !other_ip.is_empty() && other_ip != my_ip {
                if !state.war3_servers.contains_key(other_ip) {
                    info!("Creating War3Server for new client IP: {}", other_ip);
                    if let Err(e) = add_war3_server(Arc::clone(state), other_ip, Arc::clone(connection), my_ip).await {
                        error!("Failed to create War3Server for {}: {}", other_ip, e);
                    }
                }
            }
        }
    }

    // 清理不存在的客户端
    let current_ips: std::collections::HashSet<_> = client_list.client_ips.iter().collect();
    let mut to_remove = Vec::new();

    for entry in state.war3_servers.iter() {
        let ip = entry.key();
        if !current_ips.contains(ip) {
            to_remove.push(ip.clone());
        }
    }

    for ip in to_remove {
        info!("Removing War3Server for IP: {}", ip);
        state.war3_servers.remove(&ip);
    }

    Ok(())
}

/// 添加War3Server
async fn add_war3_server(
    state: Arc<ClientState>,
    other_ip: &str,
    connection: Arc<ClientConnection>,
    my_war3_ip: &str,
) -> Result<()> {
    // 检查是否已存在
    if state.war3_servers.contains_key(other_ip) {
        info!("War3Server for {} already exists", other_ip);
        return Ok(());
    }

    info!("Creating War3Server for IP: {}", other_ip);

    // 创建War3Server
    let server = Arc::new(War3Server::new(
        other_ip.to_string(),
        state.server_addr,
        state.local_war3_game_ip.to_string(),
    ));

    // 添加到状态
    state.war3_servers.insert(other_ip.to_string(), Arc::clone(&server));

    // 启动War3Server
    let my_ip = my_war3_ip.to_string();
    tokio::spawn(async move {
        if let Err(e) = server.start(connection, my_ip).await {
            error!("War3Server error: {}", e);
        }
    });

    Ok(())
}

/// 发送数据给本地War3游戏
async fn send_to_local_war3(local_ip: &IpAddr, data: &[u8]) -> Result<()> {
    // 绑定到本地IP的随机端口，避免端口冲突
    let bind_addr = format!("{}:0", local_ip);
    let socket = match UdpSocket::bind(&bind_addr).await {
        Ok(socket) => socket,
        Err(e) => {
            warn!("Failed to bind to {}, using 0.0.0.0:0: {}", bind_addr, e);
            UdpSocket::bind("0.0.0.0:0").await?
        }
    };
    socket.set_broadcast(true)?;
    
    // 获取子网广播地址，类似Java版本的实现
    let broadcast_ip = get_subnet_broadcast_address(&local_ip.to_string())
        .unwrap_or_else(|_| "255.255.255.255".to_string());
    let broadcast_addr: SocketAddr = format!("{}:{}", broadcast_ip, WAR3_PORT).parse()?;
    
    // 使用广播发送，类似Java版本的send方法
    socket.send_to(data, broadcast_addr).await?;
    info!("Sent {} bytes to local War3 game via broadcast to {}", data.len(), broadcast_addr);
    
    Ok(())
}

/// 获取子网广播地址
fn get_subnet_broadcast_address(ip_str: &str) -> Result<String> {
    // 对于远程代理场景，需要使用全局广播地址
    // 因为代理程序需要向本地网络广播UDP数据包，让本地War3游戏能够接收到
    info!("Using global broadcast address for remote proxy (IP: {})", ip_str);
    Ok("255.255.255.255".to_string())
}